/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.gui.client;

import nfse.gui.query.QueryResult;
import nfse.gui.record.FlexRecord;
import nfse.gui.util.NetUtil;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.*;
import com.gwtext.client.widgets.*;

public class TimelineTab extends FlexTable {

    FlexTable timelineDataTable = new FlexTable();

    NetFSEClient client = null;

    private int timelineN = 100;
    
    private int selected = -1;

    public TimelineTab(NetFSEClient client) {
        this.client = client;

        Hyperlink refreshTimelineButton = new Hyperlink();
        refreshTimelineButton.setHTML("Refresh");
        refreshTimelineButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                timeline(getTimelineN());
            }
        });

        Hyperlink exportTimelineButton = new Hyperlink();
        exportTimelineButton.setHTML("Export");
        exportTimelineButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                export(getTimelineN());
            }
        });

        final ListBox numResultsComboBox = new ListBox();
        numResultsComboBox.setVisibleItemCount(1);
        
        
        timelineN = 100;
        numResultsComboBox.addItem("100");
        numResultsComboBox.addItem("500");
        numResultsComboBox.addItem("1000");
        numResultsComboBox.addItem("Specify...");
        numResultsComboBox.setSelectedIndex(0);

        numResultsComboBox.addChangeListener(new ChangeListener() {
            public void onChange(Widget sender) {

                final int idx = numResultsComboBox.getSelectedIndex();
                if (idx == numResultsComboBox.getItemCount() - 1) {
                    MessageBox.prompt("Specify", "Please specify the number of records to display:",
                            new MessageBox.PromptCallback() {
                                public void execute(String btnID, String text) {
                                    if (btnID.equals("ok")) {
                                        int n = -1;
                                        try {
                                            n = Integer.parseInt(text);
                                            if (n <= 0)
                                                throw (new Exception());
                                            timelineN = n;
                                            numResultsComboBox.setItemText(idx, "" + timelineN);
                                            numResultsComboBox.addItem("Specify...");
                                            selected = idx;
                                        } catch (Exception e) {
                                            MessageBox.alert("The value specified must be an integer value > 0.");
                                            numResultsComboBox.setSelectedIndex(selected);
                                        }
                                        
                                    }
                                }
                            });

                } else {
                    timelineN = Integer.parseInt(numResultsComboBox.getItemText(idx));
                    // timeline(Integer.parseInt("" + values[idx]));
                    selected = idx;
                }
            }
        });
        

        
        // Hyperlink timelineButton = new Hyperlink("Timeline",
        // "TimelineSearchResults");
        // mergeButton.setText("Merge");

        /*
         * timelineButton.addClickListener(new ClickListener() { public void
         * onClick(Widget sender) { Vector temp = new Vector(); Iterator it =
         * checkedMyQueriesIDs.keySet().iterator(); while (it.hasNext()) {
         * String qid = (String) it.next(); temp.addElement(qid); }
         * 
         * String[] queryIDs = new String[temp.size()]; for (int i = 0; i <
         * queryIDs.length; i++) { queryIDs[i] = (String) temp.elementAt(i); }
         * timeline(queryIDs); } });
         */
        
        FlexTable timelineActionTable = new FlexTable();

        timelineActionTable.setHTML(0, 0, "<b>Actions:</b>");
        timelineActionTable.setWidget(0, 1, refreshTimelineButton);
        timelineActionTable.setWidget(0, 2, new Label("|"));
        timelineActionTable.setWidget(0, 3, exportTimelineButton);

        FlexTable timelineOptionsTable = new FlexTable();
        timelineOptionsTable.setHTML(0, 0, "<b>Options:</b>");
        timelineOptionsTable.setWidget(0, 1, new Label("# results"));
        timelineOptionsTable.setWidget(0, 2, numResultsComboBox);

        this.setWidget(0, 0, timelineOptionsTable);
        this.setWidget(1, 0, timelineActionTable);
        this.setWidget(2, 0, timelineDataTable);

    }

    private int getTimelineN() {
        return timelineN;
    }

    private synchronized void timeline(int n) {

        QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirectToHome();
            }

            public void onSuccess(Object result) {
                updateTimeline((QueryResult) result);
            }
        };

        NetFSEService.timeline(client.getQueryID(), n, client.getActiveTypes(), client.getActiveWhere(), callback);
        this.timelineN = n;
    }

   

    private void updateTimeline(QueryResult result) {
        try {
            while (timelineDataTable.getRowCount() > 1)
                timelineDataTable.removeRow(1);

            if (result == null) {

                timelineDataTable.setHTML(0, 0, "No matching results.");
                return;
            }

            // if (timelineDataTable.getRowCount() == 0) {
            timelineDataTable.setStyleName("nfsetable");
            timelineDataTable.addStyleName("nfsetbody");

            timelineDataTable.setHTML(0, 0, "<b>Start TS</b>");
            timelineDataTable.setHTML(0, 1, "<b>Src IP</b>");
            timelineDataTable.setHTML(0, 2, "<b>Src Port</b>");
            timelineDataTable.setHTML(0, 3, "<b>Dst IP</b>");
            timelineDataTable.setHTML(0, 4, "<b>Dst Port</b>");
            timelineDataTable.setHTML(0, 5, "<b>Protocol</b>");
            timelineDataTable.setHTML(0, 6, "<b>Event Data</b>");

            timelineDataTable.getRowFormatter().setStyleName(0, "nfseth");
            // }

            FlexRecord[] records = result.flexRecordGroup.records;
            for (int i = 0; i < records.length; i++) {

                if (i % 2 == 0) {
                    timelineDataTable.getRowFormatter().setStyleName(i + 1, "nfsetr");
                } else {
                    timelineDataTable.getRowFormatter().setStyleName(i + 1, "nfsetrodd");
                }

                String[] values = records[i].values;
                int colSpan = result.maxCol + 1;
                String temp = "";
                // boolean first = true;
                // /int startTSIdx = result.flexRecordGroup.getStartTSIdx();

                int idx = 5;
                for (int x = 0; x < values.length; x++) {
                    if (x == records[i].startTSIdx) {
                        timelineDataTable.setHTML(i + 1, 0, values[records[i].startTSIdx]);
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 0, "nfsetd");
                    } else if (x == records[i].srcipIdx) {
                        timelineDataTable.setHTML(i + 1, 1, values[records[i].srcipIdx]);
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 1, "nfsetd");
                    } else if (x == records[i].dstipIdx) {
                        timelineDataTable.setHTML(i + 1, 3, values[records[i].dstipIdx]);
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 3, "nfsetd");
                    } else if (x == records[i].dstportIdx) {
                        timelineDataTable.getFlexCellFormatter().addStyleName(i + 1, 4, "tdright");
                        timelineDataTable.setHTML(i + 1, 4, values[records[i].dstportIdx]);
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 4, "nfsetd");
                    } else if (x == records[i].srcportIdx) {
                        timelineDataTable.setHTML(i + 1, 2, values[records[i].srcportIdx]);
                        timelineDataTable.getFlexCellFormatter().addStyleName(i + 1, 2, "tdright");
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 2, "nfsetd");
                    } else if (x == records[i].protoIdx) {
                        String proto = values[records[i].protoIdx];
                        timelineDataTable.setHTML(i + 1, 5, NetUtil.getProtocolName(NetUtil.getProtocolValue(proto)));
                        timelineDataTable.getCellFormatter().addStyleName(i + 1, 5, "nfsetd");
                    } else {
                        temp += records[i].colNames[x] + "=" + values[x] + " ";
                    }
                }
                timelineDataTable.setHTML(i + 1, 6, temp);
                timelineDataTable.getCellFormatter().addStyleName(i + 1, 6, "nfsetd");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void export(int n) {
        String queryID = client.getQueryID();
        int[] types = client.getActiveTypes();
        String[] where = client.getActiveWhere();

        String url = "export?action=timeline&queryid=" + queryID + "&n=" + n + "&types=";
        for (int i = 0; i < types.length; i++) {
            url += types[i] + "";
            if (i != types.length - 1)
                url += " ";
        }
        for (int i = 0; i < types.length; i++) {
            if (where[i].length() > 0) {
                url += "&where" + types[i] + "=" + NetUtil.convertToHex(where[i]);
            }
        }
        Window.open(url, "Export", "");
    }

}
